home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / Src / Ch7 / Grid.frm (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1999-06-06  |  15.4 KB  |  452 lines

  1. VERSION 5.00
  2. Object = "{F9043C88-F6F2-101A-A3C9-08002B2F49FB}#1.2#0"; "COMDLG32.OCX"
  3. Begin VB.Form frmGrid 
  4.    Caption         =   "Grid []"
  5.    ClientHeight    =   2760
  6.    ClientLeft      =   165
  7.    ClientTop       =   735
  8.    ClientWidth     =   3120
  9.    LinkTopic       =   "Form2"
  10.    ScaleHeight     =   2760
  11.    ScaleWidth      =   3120
  12.    StartUpPosition =   3  'Windows Default
  13.    Begin VB.CommandButton cmdTransform 
  14.       Caption         =   "Transform"
  15.       Default         =   -1  'True
  16.       Height          =   375
  17.       Left            =   120
  18.       TabIndex        =   2
  19.       Top             =   0
  20.       Width           =   975
  21.    End
  22.    Begin VB.PictureBox picResult 
  23.       Height          =   2295
  24.       Left            =   2640
  25.       ScaleHeight     =   149
  26.       ScaleMode       =   3  'Pixel
  27.       ScaleWidth      =   157
  28.       TabIndex        =   1
  29.       Top             =   480
  30.       Width           =   2415
  31.    End
  32.    Begin MSComDlg.CommonDialog dlgOpenFile 
  33.       Left            =   0
  34.       Top             =   360
  35.       _ExtentX        =   847
  36.       _ExtentY        =   847
  37.       _Version        =   393216
  38.    End
  39.    Begin VB.PictureBox picOriginal 
  40.       AutoSize        =   -1  'True
  41.       Height          =   2295
  42.       Left            =   120
  43.       ScaleHeight     =   149
  44.       ScaleMode       =   3  'Pixel
  45.       ScaleWidth      =   157
  46.       TabIndex        =   0
  47.       Top             =   480
  48.       Width           =   2415
  49.    End
  50.    Begin VB.Menu mnuFile 
  51.       Caption         =   "&File"
  52.       Begin VB.Menu mnuFileOpen 
  53.          Caption         =   "&Open..."
  54.          Shortcut        =   ^O
  55.       End
  56.       Begin VB.Menu mnuFileSaveAs 
  57.          Caption         =   "Save &As..."
  58.          Shortcut        =   ^A
  59.       End
  60.    End
  61. Attribute VB_Name = "frmGrid"
  62. Attribute VB_GlobalNameSpace = False
  63. Attribute VB_Creatable = False
  64. Attribute VB_PredeclaredId = True
  65. Attribute VB_Exposed = False
  66. Option Explicit
  67. Private Const NUM_POINTS = 3
  68. Private PointX(0 To NUM_POINTS + 1, 0 To NUM_POINTS + 1) As Single
  69. Private PointY(0 To NUM_POINTS + 1, 0 To NUM_POINTS + 1) As Single
  70. Private GridDx As Single
  71. Private GridDy As Single
  72. Private Dragging As Boolean
  73. Private DragR As Integer
  74. Private DragC As Integer
  75. ' Transform the image.
  76. Private Sub cmdTransform_Click()
  77. Dim Dx As Single
  78. Dim Dy As Single
  79.     ' Do nothing if no picture is loaded.
  80.     If picOriginal.Picture = 0 Then Exit Sub
  81.     ' Prepare for the transformation.
  82. '    Xmax = picResult.ScaleWidth
  83. '    Ymax = picResult.ScaleHeight
  84.     Screen.MousePointer = vbHourglass
  85.     picResult.Line (0, 0)-(picResult.ScaleWidth, picResult.ScaleHeight), _
  86.         picResult.BackColor, BF
  87.     DoEvents
  88.     ' Restore the original image.
  89.     picOriginal.Cls
  90.     ' Transform the image.
  91.     TransformImage picOriginal, picResult
  92.     ' Redraw the grid.
  93.     DrawGrid
  94.     Screen.MousePointer = vbDefault
  95. End Sub
  96. ' Draw the positioning grid.
  97. Private Sub DrawGrid()
  98. Dim r As Integer
  99. Dim c As Integer
  100.     picOriginal.Cls
  101.     ' Draw the lines.
  102.     For r = 0 To NUM_POINTS
  103.         For c = 0 To NUM_POINTS
  104.             If r > 0 Then
  105.                 picOriginal.Line _
  106.                     (PointX(r, c), PointY(r, c))- _
  107.                     (PointX(r, c + 1), PointY(r, c + 1))
  108.             End If
  109.             If c > 0 Then
  110.                 picOriginal.Line _
  111.                     (PointX(r, c), PointY(r, c))- _
  112.                     (PointX(r + 1, c), PointY(r + 1, c))
  113.             End If
  114.         Next c
  115.     Next r
  116.     ' Draw the control points.
  117.     For r = 1 To NUM_POINTS
  118.         For c = 1 To NUM_POINTS
  119.             picOriginal.Line _
  120.                 (PointX(r, c) - 1, PointY(r, c) - 1)- _
  121.                 Step(3, 3), , BF
  122.         Next c
  123.     Next r
  124. End Sub
  125. ' Find the control point at this mouse position.
  126. Private Sub FindControlPoint(ByVal X As Single, ByVal Y As Single, ByRef r As Integer, ByRef c As Integer)
  127. Dim Dx As Single
  128. Dim Dy As Single
  129.     For r = 0 To NUM_POINTS + 1
  130.         For c = 0 To NUM_POINTS + 1
  131.             Dx = Abs(PointX(r, c) - X)
  132.             Dy = Abs(PointY(r, c) - Y)
  133.             If (Dx < 2) And (Dy < 2) Then Exit Sub
  134.         Next c
  135.     Next r
  136.     ' The mouse is not over a control point.
  137.     r = -1
  138.     c = -1
  139. End Sub
  140. ' Initialize the positioning grid for this picture.
  141. Private Sub InitializeGrid()
  142. Dim X As Single
  143. Dim Y As Single
  144. Dim r As Integer
  145. Dim c As Integer
  146.     GridDx = picOriginal.ScaleWidth / (NUM_POINTS + 1)
  147.     GridDy = picOriginal.ScaleHeight / (NUM_POINTS + 1)
  148.     Y = 0
  149.     For r = 0 To NUM_POINTS + 1
  150.         X = 0
  151.         For c = 0 To NUM_POINTS + 1
  152.             PointX(r, c) = X
  153.             PointY(r, c) = Y
  154.             X = X + GridDx
  155.         Next c
  156.         Y = Y + GridDy
  157.     Next r
  158. End Sub
  159. ' Map the output pixel (ix_out, iy_out) to the input
  160. ' pixel (x_in, y_in).
  161. Private Sub MapPixel(ByVal ix_out As Single, ByVal iy_out As Single, ByRef x_in As Single, ByRef y_in As Single)
  162. Dim r As Integer
  163. Dim c As Integer
  164. Dim x0 As Single
  165. Dim y0 As Single
  166. Dim dx1 As Single
  167. Dim dy1 As Single
  168. Dim dx2 As Single
  169. Dim dy2 As Single
  170. Dim v11 As Integer
  171. Dim v12 As Integer
  172. Dim v21 As Integer
  173. Dim v22 As Integer
  174.     ' See in which rectangle the point lies.
  175.     c = Int(ix_out / GridDx)
  176.     r = Int(iy_out / GridDy)
  177.     ' Find the area's upper left corner.
  178.     x0 = c * GridDx
  179.     y0 = r * GridDy
  180.     ' Map to a point in the corresponding quadrilateral
  181.     ' using bilinear interpolation.
  182.     dx1 = (ix_out - x0) / GridDx
  183.     dy1 = (iy_out - y0) / GridDy
  184.     dx2 = 1# - dx1
  185.     dy2 = 1# - dy1
  186.     ' Calculate the X value.
  187.     v11 = PointX(r, c)
  188.     v21 = PointX(r, c + 1)
  189.     v12 = PointX(r + 1, c)
  190.     v22 = PointX(r + 1, c + 1)
  191.     x_in = _
  192.         v11 * dx2 * dy2 + v12 * dx2 * dy1 + _
  193.         v21 * dx1 * dy2 + v22 * dx1 * dy1
  194.     ' Calculate the Y value.
  195.     v11 = PointY(r, c)
  196.     v21 = PointY(r, c + 1)
  197.     v12 = PointY(r + 1, c)
  198.     v22 = PointY(r + 1, c + 1)
  199.     y_in = _
  200.         v11 * dx2 * dy2 + v12 * dx2 * dy1 + _
  201.         v21 * dx1 * dy2 + v22 * dx1 * dy1
  202. End Sub
  203. ' Transform the image.
  204. Private Sub TransformImage(ByVal pic_from As PictureBox, ByVal pic_to As PictureBox)
  205. Dim white_pixel As RGBTriplet
  206. Dim input_pixels() As RGBTriplet
  207. Dim result_pixels() As RGBTriplet
  208. Dim bits_per_pixel As Integer
  209. Dim ix_max As Single
  210. Dim iy_max As Single
  211. Dim x_in As Single
  212. Dim y_in As Single
  213. Dim ix_out As Long
  214. Dim iy_out As Long
  215. Dim ix_in As Long
  216. Dim iy_in As Long
  217. Dim Dx As Single
  218. Dim Dy As Single
  219. Dim dx1 As Single
  220. Dim dx2 As Single
  221. Dim dy1 As Single
  222. Dim dy2 As Single
  223. Dim v11 As Integer
  224. Dim v12 As Integer
  225. Dim v21 As Integer
  226. Dim v22 As Integer
  227.     ' Set the white pixel's value.
  228.     With white_pixel
  229.         .rgbRed = 255
  230.         .rgbGreen = 255
  231.         .rgbBlue = 255
  232.     End With
  233.     ' Get the pixels from pic_from.
  234.     GetBitmapPixels pic_from, input_pixels, bits_per_pixel
  235.     ' Get the pixels from pic_to.
  236.     GetBitmapPixels pic_to, result_pixels, bits_per_pixel
  237.     ' Get the original image's bounds.
  238.     ix_max = pic_from.ScaleWidth - 2
  239.     iy_max = pic_from.ScaleHeight - 2
  240.     ' Calculate the output pixel values.
  241.     For iy_out = 0 To pic_to.ScaleHeight - 1
  242.         For ix_out = 0 To pic_to.ScaleWidth - 1
  243.             ' Map the pixel value from
  244.             ' (ix_out, iy_out) to (x_in, y_in).
  245.             MapPixel ix_out, iy_out, x_in, y_in
  246.             ' Interpolate to find the pixel's value.
  247.             ' Find the nearest integral position.
  248.             ix_in = Int(x_in)
  249.             iy_in = Int(y_in)
  250.             ' See if this is out of bounds.
  251.             If (ix_in < 0) Or (ix_in > ix_max) Or _
  252.                (iy_in < 0) Or (iy_in > iy_max) _
  253.             Then
  254.                 ' The point is outside the image.
  255.                 ' Use white.
  256.                 result_pixels(ix_out, iy_out) = white_pixel
  257.             Else
  258.                 ' The point lies within the image.
  259.                 ' Calculate its value.
  260.                 dx1 = x_in - ix_in
  261.                 dy1 = y_in - iy_in
  262.                 dx2 = 1# - dx1
  263.                 dy2 = 1# - dy1
  264.                 With result_pixels(ix_out, iy_out)
  265.                     ' Calculate the red value.
  266.                     v11 = input_pixels(ix_in, iy_in).rgbRed
  267.                     v12 = input_pixels(ix_in, iy_in + 1).rgbRed
  268.                     v21 = input_pixels(ix_in + 1, iy_in).rgbRed
  269.                     v22 = input_pixels(ix_in + 1, iy_in + 1).rgbRed
  270.                     .rgbRed = _
  271.                         v11 * dx2 * dy2 + v12 * dx2 * dy1 + _
  272.                         v21 * dx1 * dy2 + v22 * dx1 * dy1
  273.         
  274.                     ' Calculate the green value.
  275.                     v11 = input_pixels(ix_in, iy_in).rgbGreen
  276.                     v12 = input_pixels(ix_in, iy_in + 1).rgbGreen
  277.                     v21 = input_pixels(ix_in + 1, iy_in).rgbGreen
  278.                     v22 = input_pixels(ix_in + 1, iy_in + 1).rgbGreen
  279.                     .rgbGreen = _
  280.                         v11 * dx2 * dy2 + v12 * dx2 * dy1 + _
  281.                         v21 * dx1 * dy2 + v22 * dx1 * dy1
  282.                     ' Calculate the blue value.
  283.                     v11 = input_pixels(ix_in, iy_in).rgbBlue
  284.                     v12 = input_pixels(ix_in, iy_in + 1).rgbBlue
  285.                     v21 = input_pixels(ix_in + 1, iy_in).rgbBlue
  286.                     v22 = input_pixels(ix_in + 1, iy_in + 1).rgbBlue
  287.                     .rgbBlue = _
  288.                         v11 * dx2 * dy2 + v12 * dx2 * dy1 + _
  289.                         v21 * dx1 * dy2 + v22 * dx1 * dy1
  290.                 End With
  291.             End If
  292.         Next ix_out
  293.     Next iy_out
  294.     ' Set pic_to's pixels.
  295.     SetBitmapPixels pic_to, bits_per_pixel, result_pixels
  296.     pic_to.Picture = pic_to.Image
  297. End Sub
  298. ' Start in the current directory.
  299. Private Sub Form_Load()
  300.     picOriginal.AutoSize = True
  301.     picOriginal.ScaleMode = vbPixels
  302.     picOriginal.AutoRedraw = True
  303.     picOriginal.ForeColor = vbWhite
  304.     picResult.ScaleMode = vbPixels
  305.     picResult.AutoRedraw = True
  306.     dlgOpenFile.CancelError = True
  307.     dlgOpenFile.InitDir = App.Path
  308.     dlgOpenFile.Filter = _
  309.         "Bitmaps (*.bmp)|*.bmp|" & _
  310.         "GIFs (*.gif)|*.gif|" & _
  311.         "JPEGs (*.jpg)|*.jpg;*.jpeg|" & _
  312.         "Icons (*.ico)|*.ico|" & _
  313.         "Cursors (*.cur)|*.cur|" & _
  314.         "Run-Length Encoded (*.rle)|*.rle|" & _
  315.         "Metafiles (*.wmf)|*.wmf|" & _
  316.         "Enhanced Metafiles (*.emf)|*.emf|" & _
  317.         "Graphic Files|*.bmp;*.gif;*.jpg;*.jpeg;*.ico;*.cur;*.rle;*.wmf;*.emf|" & _
  318.         "All Files (*.*)|*.*"
  319.     Width = picResult.Left + picResult.Width + 120 + Width - ScaleWidth
  320.     Height = picResult.Top + picResult.Height + 120 + Height - ScaleHeight
  321. End Sub
  322. ' Load the indicated file.
  323. Private Sub mnuFileOpen_Click()
  324. Dim file_name As String
  325.     ' Let the user select a file.
  326.     On Error Resume Next
  327.     dlgOpenFile.Flags = cdlOFNFileMustExist + cdlOFNHideReadOnly
  328.     dlgOpenFile.ShowOpen
  329.     If Err.Number = cdlCancel Then
  330.         Exit Sub
  331.     ElseIf Err.Number <> 0 Then
  332.         Beep
  333.         MsgBox "Error selecting file.", , vbExclamation
  334.         Exit Sub
  335.     End If
  336.     On Error GoTo 0
  337.     Screen.MousePointer = vbHourglass
  338.     DoEvents
  339.     file_name = Trim$(dlgOpenFile.FileName)
  340.     dlgOpenFile.InitDir = Left$(file_name, Len(file_name) _
  341.         - Len(dlgOpenFile.FileTitle) - 1)
  342.     Caption = "Grid [" & dlgOpenFile.FileTitle & "]"
  343.     ' Open the original file.
  344.     On Error GoTo LoadError
  345.     picOriginal.Picture = LoadPicture(file_name)
  346.     On Error GoTo 0
  347.     picOriginal.Picture = picOriginal.Image
  348.     ' Draw the positioning grid.
  349.     InitializeGrid
  350.     DrawGrid
  351.     ' Arrange the controls.
  352.     picResult.Move _
  353.         picOriginal.Left + picOriginal.Width + 120, _
  354.         picOriginal.Top, picOriginal.Width, _
  355.         picOriginal.Height
  356.     picResult.Line (0, 0)-(picResult.ScaleWidth, picResult.ScaleHeight), _
  357.         picResult.BackColor, BF
  358.     picResult.Picture = picResult.Image
  359.     Width = picResult.Left + picResult.Width + 120 + Width - ScaleWidth
  360.     Height = picResult.Top + picResult.Height + 120 + Height - ScaleHeight
  361.     Screen.MousePointer = vbDefault
  362.     Exit Sub
  363. LoadError:
  364.     Screen.MousePointer = vbDefault
  365.     MsgBox "Error " & Format$(Err.Number) & _
  366.         " opening file '" & file_name & "'" & vbCrLf & _
  367.         Err.Description
  368. End Sub
  369. ' Save the transformed image.
  370. Private Sub mnuFileSaveAs_Click()
  371. Dim file_name As String
  372.     ' Let the user select a file.
  373.     On Error Resume Next
  374.     dlgOpenFile.Flags = cdlOFNOverwritePrompt + cdlOFNHideReadOnly
  375.     dlgOpenFile.ShowSave
  376.     If Err.Number = cdlCancel Then
  377.         Exit Sub
  378.     ElseIf Err.Number <> 0 Then
  379.         Beep
  380.         MsgBox "Error selecting file.", , vbExclamation
  381.         Exit Sub
  382.     End If
  383.     On Error GoTo 0
  384.     Screen.MousePointer = vbHourglass
  385.     DoEvents
  386.     file_name = Trim$(dlgOpenFile.FileName)
  387.     dlgOpenFile.InitDir = Left$(file_name, Len(file_name) _
  388.         - Len(dlgOpenFile.FileTitle) - 1)
  389.     Caption = "Grid [" & dlgOpenFile.FileTitle & "]"
  390.     ' Save the transformed image into the file.
  391.     On Error GoTo SaveError
  392.     SavePicture picResult.Picture, file_name
  393.     On Error GoTo 0
  394.     Screen.MousePointer = vbDefault
  395.     Exit Sub
  396. SaveError:
  397.     Screen.MousePointer = vbDefault
  398.     MsgBox "Error " & Format$(Err.Number) & _
  399.         " saving file '" & file_name & "'" & vbCrLf & _
  400.         Err.Description
  401. End Sub
  402. ' Start dragging a control point.
  403. Private Sub picOriginal_MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
  404.     ' See if the mouse is over a control point.
  405.     FindControlPoint X, Y, DragR, DragC
  406. End Sub
  407. ' Move a control point.
  408. Private Sub picOriginal_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
  409. Dim row As Integer
  410. Dim col As Integer
  411.     ' Do nothing if we are not dragging.
  412.     If DragR < 0 Then
  413.         ' No drag is in progress.
  414.         ' See if the mouse is over a control point.
  415.         FindControlPoint X, Y, row, col
  416.         If row >= 0 Then
  417.             ' We're over a control point. Display
  418.             ' the crosshair cursor.
  419.             If picOriginal.MousePointer <> vbCrosshair Then
  420.                 picOriginal.MousePointer = vbCrosshair
  421.             End If
  422.         Else
  423.             ' We're not over a control point. Display
  424.             ' the default cursor.
  425.             If picOriginal.MousePointer <> vbDefault Then
  426.                 picOriginal.MousePointer = vbDefault
  427.             End If
  428.         End If
  429.     Else
  430.         ' A drag is in progress.
  431.         ' Make sure the point stays in bounds.
  432.         If X < 1 Then X = 1
  433.         If X > picOriginal.ScaleWidth Then X = picOriginal.ScaleWidth
  434.         If Y < 1 Then Y = 1
  435.         If Y > picOriginal.ScaleHeight Then Y = picOriginal.ScaleHeight
  436.         ' Make sure edge points stay on the edge.
  437.         If DragC = 0 Then X = 0
  438.         If DragC = NUM_POINTS + 1 Then X = picOriginal.ScaleWidth
  439.         If DragR = 0 Then Y = 0
  440.         If DragR = NUM_POINTS + 1 Then Y = picOriginal.ScaleHeight
  441.         ' Move the control point.
  442.         PointX(DragR, DragC) = X
  443.         PointY(DragR, DragC) = Y
  444.         ' Redraw the control grid.
  445.         DrawGrid
  446.     End If
  447. End Sub
  448. ' Finish moving a control point.
  449. Private Sub picOriginal_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
  450.     DragR = -1
  451. End Sub
  452.